﻿using System;
using System.IO;
using System.Collections.Generic;

using System.Text;
using System.Xml;
using Estimate.Common.DBFieldTypes;
using Estimate.Common.Repository;
using Estimate.Common.Entity;

namespace Estimate.Common.DataImporter
{
    /// <summary>
    /// 将李进喜处理的自动站实况文件读入数据库
    /// </summary>
    public class AutoStationImporter : IDataImporter
    {
        protected RainRealRepository rainRepository;

        protected TempRealRepository tempRepository;

        protected RealDataLogRepository logRepository;

        protected ImportDataQuality quality;

        public AutoStationImporter(RainRealRepository rain,TempRealRepository temp,RealDataLogRepository log,string[] stations)
        {
            rainRepository = rain;

            tempRepository = temp;

            logRepository = log;

            quality = new ImportDataQuality( stations);
        }

        /// <summary>
        /// //某个时次的一个预报XML入库
        /// </summary>
        /// <param name="filepath">xml文件路径</param>
        public void ImportDataFromFile(string filepath)
        {           
            string datestr = Path.GetFileNameWithoutExtension(filepath).Substring(4, 8);
            DateTime date = new DateTime(Convert.ToInt32(datestr.Substring(0, 4)), Convert.ToInt32(datestr.Substring(4, 2)), Convert.ToInt32(datestr.Substring(6, 2)));
            ImportDataFromFileWithDate(filepath, date);
        }


        public void ImportDataFromFileWithDate(string filepath, DateTime dt)
        {
            quality.Clear();
            RealDataLogEntity logEntity = new RealDataLogEntity(ForeSemiType.Auto,dt, filepath);
            if (logRepository.IsRealDataExist(ForeSemiType.Auto, dt))
            {
              logEntity =   logRepository.GetRealDataWithDate(ForeSemiType.Auto, dt);
              logEntity.Error = 0;
              logEntity.Lack = 0;
              logEntity.FilePath = filepath;
              logEntity.ReimportCount += 1;
              logEntity.LastImportTime = DateTime.Now;
            }           
            
            XmlTextReader xtr = new XmlTextReader(filepath);
            string st = "";
            List<string> r82 = new List<string>();
            List<string> r28 = new List<string>();
            List<string> r88 = new List<string>();
            List<string> r22 = new List<string>();
            List<string> tn8 = new List<string>();
            List<string> tx8 = new List<string>();
            List<string> tn2 = new List<string>();
            List<string> tx2 = new List<string>();

            while (xtr.Read())
            {
                XmlNodeType nType = xtr.NodeType;

                if (nType == XmlNodeType.Element && xtr.Name != "SpotList" && xtr.Name != "Items")
                {
                    if (xtr.Name.ToString() == "Stn")
                    {
                        xtr.Read();
                        st = xtr.Value.ToString();
                        quality.ProvideStation(st);
                    }
                    else if (xtr.Name.ToString() == "r82")
                    {
                        xtr.Read();
                        r82.Add(st + ";" + xtr.Value.ToString());
                        
                    }
                    else if (xtr.Name.ToString() == "r28")
                    {
                        xtr.Read();
                        r28.Add(st + ";" + xtr.Value.ToString());
                    }
                    else if (xtr.Name.ToString() == "r88")
                    {
                        xtr.Read();
                        r88.Add(st + ";" + xtr.Value.ToString());
                    }
                    else if (xtr.Name.ToString() == "r22")
                    {
                        xtr.Read();
                        r22.Add(st + ";" + xtr.Value.ToString());
                    }
                    else if (xtr.Name.ToString() == "Tmin8")
                    {
                        xtr.Read();
                        tn8.Add(st + ";" + xtr.Value.ToString());

                        float value = Convert.ToSingle(xtr.Value.ToString());

                        if (value < -10f || value > 45f)
                        {
                            quality.AddError(string.Format("{0}-{1}-{2}-{3}", st, "Tmin8", "ErrorValue", xtr.Value.ToString()));
                        }
                    }
                    else if (xtr.Name.ToString() == "Tmax8")
                    {
                        xtr.Read();
                        tx8.Add(st + ";" + xtr.Value.ToString());

                        float value = Convert.ToSingle(xtr.Value.ToString());
                        if (value < -10f || value > 45f)
                        {
                            quality.AddError(string.Format("{0}-{1}-{2}-{3}", st, "Tmax8", "ErrorValue", xtr.Value.ToString()));
                        }
                    }
                    else if (xtr.Name.ToString() == "Tmin2")
                    {
                        xtr.Read();
                        tn2.Add(st + ";" + xtr.Value.ToString());

                        float value = Convert.ToSingle(xtr.Value.ToString());
                        if (value < -10f || value > 45f)
                        {
                            quality.AddError(string.Format("{0}-{1}-{2}-{3}", st, "Tmin2", "ErrorValue", xtr.Value.ToString()));
                        }
                    }
                    else if (xtr.Name.ToString() == "Tmax2")
                    {
                        xtr.Read();
                        tx2.Add(st + ";" + xtr.Value.ToString());

                        float value = Convert.ToSingle(xtr.Value.ToString());
                        if (value < -10f || value > 45f)
                        {
                            quality.AddError(string.Format("{0}-{1}-{2}-{3}", st, "Tmax2", "ErrorValue", xtr.Value.ToString()));
                        }
                    }
                    else
                    {//天气现象不在编码范围内，Error
                        quality.AddError(string.Format("{0}-{1}-{2}", st, xtr.Name.ToString(), "ErrorFactor"));
                    }
                    
                }

            }
            RainRealEntity rainEntity = new RainRealEntity(dt, RealRainValueType.D82, string.Join("|", r82.ToArray()));
            rainRepository.SetValue(rainEntity);
            AfterDataBeSaved(rainEntity);

            rainEntity = new RainRealEntity(dt, RealRainValueType.D28, string.Join("|", r28.ToArray()));
            rainRepository.SetValue(rainEntity);
            AfterDataBeSaved(rainEntity);

            rainEntity = new RainRealEntity(dt, RealRainValueType.D88, string.Join("|", r88.ToArray()));
            rainRepository.SetValue(rainEntity);
            AfterDataBeSaved(rainEntity);

            rainEntity = new RainRealEntity(dt, RealRainValueType.D22, string.Join("|", r22.ToArray()));
            rainRepository.SetValue(rainEntity);
            AfterDataBeSaved(rainEntity);

            TempRealEntity tempEntity = new TempRealEntity(dt, RealTempValueType.D8, string.Join("|", tn8.ToArray()));
            tempRepository.SetValue(tempEntity);
            AfterDataBeSaved(tempEntity);

            tempEntity = new TempRealEntity(dt, RealTempValueType.D18, string.Join("|", tx8.ToArray()));
            tempRepository.SetValue(tempEntity);
            AfterDataBeSaved(tempEntity);

            tempEntity = new TempRealEntity(dt, RealTempValueType.D2, string.Join("|", tn2.ToArray()));
            tempRepository.SetValue(tempEntity);
            AfterDataBeSaved(tempEntity);

            tempEntity = new TempRealEntity(dt, RealTempValueType.D12, string.Join("|", tx2.ToArray()));
            tempRepository.SetValue(tempEntity);
            AfterDataBeSaved(tempEntity);

            logEntity.Error = quality.ErrorCount;
            logEntity.ErrorString = quality.ErrorString;
            logEntity.Lack = quality.LackCount;
            logEntity.LackString = quality.LackString;
            logRepository.SetRecord(logEntity);
        }


        public event EventHandler AfterDataInDatabase;

        public void AfterDataBeSaved(RainRealEntity entity)
        {
            object data = entity.Clone();
            if (AfterDataInDatabase != null)
            {
                AfterDataInDatabase(this, new FindDataEventArgs(data));
            }
        }

        public void AfterDataBeSaved(TempRealEntity entity)
        {
            object data = entity.Clone();
            if (AfterDataInDatabase != null)
            {
                AfterDataInDatabase(this, new FindDataEventArgs(data));
            }
        }



        /// <summary>
        /// 未实现该事件。目前用不到
        /// </summary>
        public event EventHandler BeforeDataInDatabase;


    }
}
